﻿using Freebase4net.Operators;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Freebase4net.Tests
{
    [TestClass]
    public class MqlReadServiceAsyncTests
    {
        private MqlReadService _readService;

        public MqlReadServiceAsyncTests()
        {
            _readService = FreebaseServicesBuilder.CreateMqlReadService();
        }

        [TestMethod]
        public async Task ReadAsync_ObjectWithLikeOperator_StatusCodeOk()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.id = null;
            thepolice.type = "/film/film";
            thepolice.name = new LikeOperator("^The *$");

            MqlReadServiceResponse result = await _readService.ReadAsync(thepolice);

            Assert.AreEqual("/film/film", (string)result.Results[0].type);
            Assert.AreEqual(System.Net.HttpStatusCode.OK, result.Status);
        }

        [TestMethod]
        public async Task ReadAsync_DictionaryOfObjects_StatusCodeOk()
        {
            dynamic thepolice = new ExpandoObject();
            thepolice.type = "/music/artist";
            thepolice.name = "The Scorpions";
            thepolice.album = new Dictionary<Object, Object>();
            thepolice.album.Add("name", null);
            thepolice.album.Add("limit", 2);
            thepolice.album.Add("genre", Freeb.CreateArrayWithEmptyObject());


            var result = await _readService.ReadAsync(thepolice);


            Assert.AreEqual(System.Net.HttpStatusCode.OK, result.Status);
        }

        [TestMethod]
        public async Task ReadAsync_ComplexEmbeddedObject_StatusCodeOk()
        {
            dynamic director = new ExpandoObject();
            director.name = null;
            director.id = null;
            director.type = "/film/editor";
            director.film = new Dictionary<Object, Object>() {
                {"name",null},
                {"id",null},
                {"starring",new Dictionary<Object,Object>()
                    {
                        {"actor", "Theresa Russell"}
                    }
                }
            };


            var result = await _readService.ReadAsync(director);


            Assert.AreEqual(System.Net.HttpStatusCode.OK, result.Status);
        }

        [TestMethod]
        public void ReadMultipleAsync_MultipleQueriesWithTasksAsResponse_StatusCodeOk()
        {
            dynamic thescorpions = new ExpandoObject();
            thescorpions.name = "The Scorpions";
            thescorpions.type = "/music/artist";

            dynamic thepolice = new ExpandoObject();
            thepolice.name = "The Police";
            thepolice.type = "/music/artist";

            MultipleMqlReadServiceAsyncResponse multiFreebaseResponse = _readService.ReadMultipleAsync(thescorpions, thepolice);
            Task.WaitAll(multiFreebaseResponse.Results.ToArray());

            foreach (var t in multiFreebaseResponse.Results)
            {
                Assert.AreEqual(System.Net.HttpStatusCode.OK, t.Result.Status);
            }
        }

        [TestMethod]
        public void ReadMultipleAsync_MultipleQueriesWithReadyResults_StatusCodeOk()
        {
            dynamic thescorpions = new ExpandoObject();
            thescorpions.name = "The Scorpions";
            thescorpions.type = "/music/artist";

            dynamic thepolice = new ExpandoObject();
            thepolice.name = "The Police";
            thepolice.type = "/music/artist";

            List<MqlReadServiceResponse> multiFreebaseResponse = _readService.ReadMultipleAsyncWithWait(thescorpions, thepolice);

            foreach (var t in multiFreebaseResponse)
            {
                Assert.AreEqual(System.Net.HttpStatusCode.OK, t.Status);
            }
        }
    }
}
